﻿using Kylin.Wiki.Core.Enum;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Kylin.Wiki.Services
{
    public interface IServices<T>  where T : class, new()
    {

        #region 简单查询
        /// <summary>
        /// 按ID查询
        /// </summary>
        /// <param name="objId">实体ID</param>
        /// <returns></returns>
        T FindFirst(Expression<Func<T, bool>> where);

        /// <summary>
        /// 异步按条件查询
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        Task<T> FindFirstAsync(Expression<Func<T, bool>> where);

        /// <summary>
        /// 根据条件查询数据是否存在
        /// </summary>
        /// <param name="where">条件表达式树</param>
        /// <returns></returns>
        bool Exists(Expression<Func<T, bool>> where);

        /// <summary>
        /// 异步根据条件查询数据是否存在
        /// </summary>
        /// <param name="where">条件表达式树</param>
        /// <returns></returns>
        Task<bool> ExistsAsync(Expression<Func<T, bool>> where);

        /// <summary>
        /// 通过条件查询数据
        /// </summary>
        /// <param name="objIds"></param>
        /// <returns></returns>
        List<T> Find(Expression<Func<T, bool>> where);


        /// <summary>
        /// 异步通过条件查询数据
        /// </summary>
        /// <param name="objIds"></param>
        /// <returns></returns>
        Task<List<T>> FindAsync(Expression<Func<T, bool>> where);

        /// <summary>
        /// 通过条件查询数据
        /// </summary>
        /// <param name="predicate">where条件</param>
        /// <param name="orderBy">排序字段,数据格式如:
        ///  orderBy = x => new Dictionary<object, bool>() {
        ///          { x.BalconyName,QueryOrderBy.Asc},
        ///          { x.TranCorpCode1,QueryOrderBy.Desc}
        ///         };
        /// </param>
        /// <returns></returns> 
        IQueryable<T> FindAsIQueryable(Expression<Func<T, bool>> predicate, Expression<Func<T, Dictionary<object, QueryOrderBy>>> orderBy = null);

        /// <summary>
        /// 通过条件查询数据
        /// </summary>
        /// <param name="predicate"></param>
        /// <param name="orderBy"></param>
        /// <returns></returns>
        Task<List<T>> Find(Expression<Func<T, bool>> predicate, Expression<Func<T, Dictionary<object, QueryOrderBy>>> orderBy = null);

        /// <summary>
        /// 通过条件查询数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="predicate">查询条件</param>
        /// <param name="selector">返回类型如:Find(x => x.UserName == loginInfo.userName, p => new { uname = p.UserName });</param>
        /// <returns></returns>
        List<T> Find<TReulst>(Expression<Func<T, bool>> predicate, Expression<Func<T, T>> selector);

        /// <summary>
        /// 异步通过条件查询数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="predicate">查询条件</param>
        /// <param name="selector">返回类型如:Find(x => x.UserName == loginInfo.userName, p => new { uname = p.UserName });</param>
        /// <returns></returns>
        Task<List<T>> FindAsync<TReulst>(Expression<Func<T, bool>> predicate, Expression<Func<T, T>> selector);

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pagesize"></param>
        /// <param name="rowcount"></param>
        /// <param name="predicate"></param>
        /// <param name="orderBy"></param>
        /// <param name="returnRowCount"></param>
        /// <returns></returns>
        List<T> QueryablePage(int pageIndex, int pagesize, out int rowcount, Expression<Func<T, bool>> predicate, Dictionary<string, QueryOrderBy> orderBy, bool returnRowCount = true);
         

        #endregion

        #region 添加操作
        /// <summary>
        /// 添加数据
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="SaveChanges"></param>
        int Add(T entities, bool SaveChanges = false);

        /// <summary>
        /// 批量添加
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="SaveChanges"></param>
        int AddRange(IEnumerable<T> entities, bool SaveChanges = false);
        #endregion

        #region 删除操作 

        /// <summary>
        /// 按Entity删除数据
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        int Delete(T model, bool saveChanges = false);

        #endregion

        #region 修改操作

        /// <summary>
        /// 根据Entity修改数据（注意会修改所有字段值）
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        int Update(T entity, bool saveChanges = false);

        /// <summary>
        /// 根据Entity修改数据（指定字段）
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="updatedProperties"></param>
        /// <param name="saveChanges"></param>
        /// <returns></returns>
        int Update(T entity, Expression<Func<T, object>>[] updatedProperties, bool saveChanges = false);

        /// <summary>
        /// 批量修改数据（注意会修改所有字段值）
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        int Update(List<T> entities, bool saveChanges = false);

        #endregion

        #region 复杂查询 

        /// <summary>
        /// 多表联合查询
        /// </summary>
        /// <typeparam name="T1">表1</typeparam>
        /// <typeparam name="T2">表2</typeparam>
        /// <typeparam name="TResult">返回结果</typeparam>
        /// <param name="joinExpression">join表达式</param>
        /// <param name="selectExpression">select表达式</param>
        /// <param name="whereLambda">where 表达式</param>
        /// <returns></returns>
        //Task<List<TResult>> QueryMuch<T1, T2, TResult>(
        //    Expression<Func<T1, T2, object[]>> joinExpression,
        //    Expression<Func<T1, T2, TResult>> selectExpression,
        //    Expression<Func<T1, T2, bool>> whereLambda = null) where T1 : class, new();

        /// <summary>
        /// 多表联合查询
        /// </summary>
        /// <typeparam name="E">表1</typeparam>
        /// <typeparam name="T2">表2</typeparam>
        /// <typeparam name="T3">表3</typeparam>
        /// <typeparam name="TResult">返回结果</typeparam>
        /// <param name="joinExpression">join表达式</param>
        /// <param name="selectExpression">select表达式</param>
        /// <param name="whereLambda">where 表达式</param>
        /// <returns></returns>
        //Task<List<TResult>> QueryMuch<Tentity1, Tentity2, Tentity3, TResult>(
        //    Expression<Func<Tentity1, Tentity2, Tentity3, object[]>> joinExpression,
        //    Expression<Func<Tentity1, Tentity2, Tentity3, TResult>> selectExpression,
        //    Expression<Func<Tentity1, Tentity2, Tentity3, bool>> whereLambda = null) where Tentity1 : class, new();


        /// <summary>
        /// 分页查询数据
        /// </summary>
        /// <param name="where">条件表达式</param>
        /// <param name="pageInput">分页参数</param>
        /// <param name="order">排序表达式</param>
        /// <param name="orderEnum">排序类型(Desc,Asc)</param>
        /// <returns></returns>
        //Task<PageOption> QueryPage(Expression<Func<T, bool>> where, PageOption pageInput, Expression<Func<T, object>> order = null, string orderEnum = "Asc");

        #endregion

    }

}
